package com.changgou.seckill.task;

import com.alibaba.fastjson.JSON;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.seckill.pojo.SeckillOrder;
import entity.IdWorker;
import entity.SeckillStatus;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author ：hushengjin
 */

@Component
public class MultiThreadingCreateOrder {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private Environment env;

    @Async
    public void createOrder() {
        //从队列中获取排队信息
        SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundListOps("SeckillOrderQueue").rightPop();
        try {
            if (seckillStatus != null) {
                //从队列中获取一个商品
                Object sgood = redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillStatus.getGoodsId()).rightPop();
                if (sgood == null) {
                    //清理当前用户排队信息
                    clearQueue(seckillStatus);
                    return;
                }
                //登录名
                String username = seckillStatus.getUsername();
                //时区
                String time = seckillStatus.getTime();
                //商品id
                Long id = seckillStatus.getGoodsId();
                //先获取秒杀商品
                SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps("SeckillGoods_" + time).get(id);
                if (seckillGoods == null || seckillGoods.getStockCount() <= 0) {
                    throw new RuntimeException("已售罄! ");
                }
                //如果有库存,添加秒杀商品订单
                SeckillOrder seckillOrder = new SeckillOrder();
                seckillOrder.setId(idWorker.nextId());
                seckillOrder.setSeckillId(seckillGoods.getId());
                seckillOrder.setMoney(seckillGoods.getCostPrice());
                seckillOrder.setUserId(username);
                seckillOrder.setCreateTime(new Date());
                seckillOrder.setStatus("0");
                //将秒杀订单存入redis中
                redisTemplate.boundHashOps("SeckillOrder").put(username, seckillOrder);
                //库存减少
                Long seckillGoodsCount = redisTemplate.boundHashOps("SeckillGoodsCount").increment(id, -1);

                //判断当前商品是否还有库存
                if (seckillGoodsCount <= 0) {
                    //将商品同步到数据库中
                    seckillGoodsMapper.updateByPrimaryKeySelective(seckillGoods);
                    //清空redis中的数据
                    redisTemplate.boundHashOps("SeckillGoods_" + time).delete(id);
                } else {
                    //有库存,重置redis中的数据
                    redisTemplate.boundHashOps("SeckillGoods_").put(id, seckillGoods);
                }
                //抢单成功,更新抢单状态 排队 -> 等待支付
                seckillStatus.setStatus(2);
                seckillStatus.setOrderId(seckillOrder.getId());
                seckillStatus.setMoney(seckillOrder.getMoney());
                redisTemplate.boundHashOps("UserQueueStatus").put(username, seckillStatus);
                sendTimerMessage(seckillStatus);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 清理用户排队信息
     *
     * @param seckillStatus
     */
    public void clearQueue(SeckillStatus seckillStatus) {
        //清理排队标识
        redisTemplate.boundHashOps("UserQueueCount").delete(seckillStatus.getUsername());

        //清理抢单标识
        redisTemplate.boundHashOps("UserQueueStatus").delete(seckillStatus.getUsername());
    }

    /**
     * 发送延时消息到RabbitMQ中
     *
     * @param seckillStatus
     */
    public void sendTimerMessage(SeckillStatus seckillStatus) {
        rabbitTemplate.convertAndSend(env.getProperty("mq.pay.queue.seckillordertimerdelay"), (Object) JSON.toJSONString(seckillStatus), new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration("30*60*1000");
                return message;
            }
        });
    }

}
